using System;
using System.Configuration;
using System.Globalization;
using System.Web;

using System.Xml;
using System.Xml.Xsl;

/*	-----------------------------------------------------------------------	
	Copyright:	umlungu consulting (pty) ltd
	Author:		Alan Benington	
	Started:	2006-03-08	
	Status:		release	
	Version:	1.0.5.20060904
	License:	GNU General Public License
	-----------------------------------------------------------------------	*/
	
/*	-----------------------------------------------------------------------	
	Development Notes:
	 -	This Class has the following hierarchy:
		blogpageX
			|_ uiX
				|_ pageX
					|_ System.Web.UI.Page
	 -	This class follows the paradigm where functionality that is driven by
	 	form submission has an hidden 'Action' form field from which the type
		of action is identified. This class contains the following standard 
		actions:
			- ChangeTime
			- AddComment
			- AddRecruit
			- AddSubscriber
	 -	Actions are called in the _ProcessAction and _LoadAdditional methods.
	 	These methods may be overridden in derived classes to provide custom 
		actions.
	---------------------------------------------------------------------------	*/

namespace umlungu.engineX.blogX {
	/// <summary>
	/// umlungu engineX blog page class.
	/// </summary>
	public class blogpageX : uiX {
		#region Invisible properties
		private string action;
		private x_recruit recruitx;
		
		// Names of form fields for the comment form
		private const string Comment_name = "Comment_name";
		private const string Comment_topic = "Comment_topic";
		private const string Comment_archive = "Comment_archive";
		private const string Comment_id = "Comment_id";
		private const string Comment_author = "Comment_author";
		private const string Comment_title = "Comment_title";
		private const string Comment = "Comment";
		
		// Names of form fields for the recruit/subscriber form
		private const string Recruit_space = "Recruit_space";
		private const string Recruit_email = "Recruit_email";
		private const string Recruit_ID = "RecruitID";
		
		// Name of form field for month changer
		private const string Current_month = "CurrentMonth";
		
		// Spam words and error
		private const string error_content_spam = "Content contains non-permitted words";
		private string spam_list = "http|[url|mailto|fuck|cialis";
		
		// Names of form fields for the recruit/subscriber form
		private const string Subscriber_space = "Space";
		private const string Subscriber_username = "Email";
		private const string Subscriber_firstname = "FirstName";
		private const string Subscriber_lastname = "LastName";
		private const string Subscriber_email = "Email";
		private const string Subscriber_telno = "Phone";
		private const string Subscriber_field1 = "Field1";
		private const string Subscriber_field2 = "Field2";
		private const string Subscriber_field3 = "Field3";
		private const string Subscriber_field4 = "Field4";
		private const string Subscriber_group = "Group";
		private const string Subscriber_secret = "Secret";
		private const string Subscriber_password = "Password";
		// Default values
		private const string Default_username = "anonymous";
		private const string Default_firstname = "[FirstName]";
		private const string Default_lastname = "[LastName]";
		private const string Default_email = "[Email]";
		private const string Default_telno = "[Phone]";
		private const string Default_group = "public";
		private const string Default_secret = "umlungu";
		private const string Default_passw = "password";
		#endregion

		#region Visible properties
		private string property;
		/// <summary>Definiton of the property</summary>
		/// <value>Description of the value of the property</value>
		public string Property {
			get { return property; }
			set { property = value; }
		}
		#endregion

		#region Constructors/Destructors
		/// <overloads>Constructor</overloads>
		/// <summary>Default constructor</summary>
		public blogpageX() : base("blogpageX") {
		}
		/// <summary>Constructor</summary>
		public blogpageX(string thisid) : base(thisid) {
		}
		#endregion
		
		#region Public methods
		#endregion

		#region Protected methods
		/// <summary>Processes an action defined by the submission of a form with the 'Action' field.</summary>
		protected override void _ProcessAction() {
			action = FormOrQuery("Action");
			switch(action) {
				case "ChangeTime":			changeTime();		break;
				case "AddComment":			addComment();		break;
				case "AddRecruit":			addRecruit();		break;
				case "ConfirmSubscriber":	confirmRecruit();	break;
				case "AddSubscriber":		addSubscriber();	break;
				case "DeleteSubscriber":	deleteSubscriber();	break;
				default:	break;
			}
		}
		/// <summary>Loads additional information</summary>
		protected override void _LoadAdditional() {
			loadExtra();
			loadTime();
			switch(action) {
				case "ConfirmSubscriber":
				case "AddRecruit":			loadRecruit();	break;
			}
		}
		#endregion

		#region Private methods
		/// <summary>Loads and appends any extra data (originally from displayX.aspx.cs)</summary>
		/// <remarks>
		/// All errors in loading the extra xml data (file existence or parseError) are caught.
		/// This means errors result in the page loading without the extra xml data.
		/// </remarks>
		private void loadExtra() {
			XmlDocument extra = new XmlDocument();
			try {
				extra.Load(String.Concat(Application["ExtraPathX"], "/extras.xml"));
				Blogs.AppendChild(BlogXml.ImportNode(extra.DocumentElement, true));
			} catch(System.Exception e) {
				if (Debug) {
					x_result error = new x_result("BlogX");
					x_exception xe = new x_exception("error_extra", e.Message);
					error.AddError(xe);
					Blogs.AppendChild(BlogXml.ImportNode(error.Result.DocumentElement, true));
				}
			}
		}
		/// <summary>
		/// Loads the time from the DateTimeX Session object (or else from the current time) into xsl template parameters.
		/// </summary>
		private void loadTime() {
			DateTime now = (Session["DateTimeX"] == null)? DateTime.Now : (DateTime)Session["DateTimeX"];
			string date = now.ToString("s", DateTimeFormatInfo.InvariantInfo);
			string day = now.Day.ToString();
			string month = now.Month.ToString();
			string year = now.Year.ToString();
			TemplateArgs.AddParam("now", "", date);
			TemplateArgs.AddParam("day", "", day);
			TemplateArgs.AddParam("month", "", month);
			TemplateArgs.AddParam("year", "", year);
			if (Debugger.Enabled) {
				Blogs.SetAttribute("now", date);
				Blogs.SetAttribute("day", day);
				Blogs.SetAttribute("month", month);
				Blogs.SetAttribute("year", year);
			}
		}
		/// <summary>
		/// Changes the value of the DateTimeX Session object
		/// </summary>
		private void changeTime() {
			DateTime newdate;
			string month = FormField(Current_month);
			int mnth = Convert.ToInt32(month);
			if (month != "" && month != "0") {
				if (mnth == DateTime.Now.Month)	// ie set to this month - use current date
					newdate = DateTime.Now;
				else	// set to another month with the last day of the month as current date
					newdate = new DateTime(DateTime.Now.Year, mnth, DateTime.DaysInMonth(DateTime.Now.Year, mnth));
				Session.Add("DateTimeX", newdate);
			}
		}
		/// <summary>
		/// Adds a comment from the comment submission form
		/// </summary>
		private void addComment() {
			x_blog blogx = new x_blog(Application);
			if (FormField(Comment_archive) == "")
				blogx.AddComment(FormField(Comment_name), FormField(Comment_topic), System.Convert.ToInt32(FormField(Comment_id)), "public", FormField(Comment_author, "[unknown author]"), FormField(Comment_title, "[no title]"), FormField(Comment, "[no comment]"));
			else
				blogx.AddComment(FormField(Comment_name), FormField(Comment_topic), FormField(Comment_archive), System.Convert.ToInt32(FormField(Comment_id)), "public", FormField(Comment_author, "[unknown author]"), FormField(Comment_title, "[no title]"), FormField(Comment, "[no comment]"));
		}
	/*	Comment since this might be hangover from old version (1.0.3) in consolidation
		private void postComment() {
			x_blog blogx = new x_blog(Application);
			if (_commentarchive == "")
				blogx.AddComment(_commentname, _commenttopic, System.Convert.ToInt32(_commentid), "public", _commentauthor, _commenttitle, _commenttext);
			else
				blogx.AddComment(_commentname, _commenttopic, _commentarchive, System.Convert.ToInt32(_commentid), "public", _commentauthor, _commenttitle, _commenttext);
		}
		private bool loadComment() {
			_commentname = FormField(Comment_name);
			_commenttopic = FormField(Comment_topic);
			_commentarchive = FormField(Comment_archive);
			_commentid = FormField(Comment_id);
			_commentauthor = FormField(Comment_author, "[unknown author]");
			_commenttitle = FormField(Comment_title, "[no title]");
			_commenttext = FormField(Comment, "[no comment]");
			bool titlespam = spamCheck(spam_list, _commenttitle, false);
			bool textspam = spamCheck(spam_list, _commenttext, false);
			bool spam = (titlespam || textspam);
			return !spam;
		}
	*/
		/// <summary>
		/// Adds a recruit form the subscribe/recruit submission form
		/// </summary>
		private void addRecruit() {
			try {
				recruitx = new x_recruit(Application);
				recruitx.Add(FormField(Recruit_space), FormField(Recruit_email));
				recruitx.SendConfirmation(FormField(Recruit_space));
			} catch(x_exception e) {
				throw(new x_glitch(this, e.Code, e.Message));
			} catch(Exception e) {
				throw(new x_glitch(this, "error_recruit", e.Message));
			}
		}
		/// <summary>
		/// Adds a recruit form the subscribe/recruit submission form
		/// </summary>
		private void confirmRecruit() {
			try {
				recruitx = new x_recruit(Application);
				recruitx.Get(QueryParam(Recruit_ID));
			} catch(x_exception e) {
				throw(new x_glitch(this, e.Code, e.Message));
			} catch(Exception e) {
				throw(new x_glitch(this, "error_recruit", e.Message));
			}
		}
		/// <summary>
		/// Loads the recruit object (if created) as a parameter of the xsl template
		/// </summary>
		private void loadRecruit() {
			TemplateArgs.AddParam("recruit", "", (recruitx == null)? null : recruitx.Recruit);
		}
		/// <summary>
		/// Adds a subscriber to BlogSpace from the fields on the submission form
		/// </summary>
		private void addSubscriber() {
			string name = FormField(Subscriber_space, Name);
			string username = FormField(Subscriber_username, Default_username);
			string firstname = FormField(Subscriber_firstname, Default_firstname);
			string lastname = FormField(Subscriber_lastname, Default_lastname);
			string email = FormField(Subscriber_email, Default_email);
			string telno = FormField(Subscriber_telno, Default_telno);
			string group = FormField(Subscriber_group, Default_group);
			string secret = FormField(Subscriber_secret, Default_secret);
			string password = FormField(Subscriber_password, Default_passw);
			
			x_user userx = new x_user(Application);
			try {
				userx.Add(username, firstname, lastname, email, telno, secret, password, group, FormField(Subscriber_field1), FormField(Subscriber_field2), FormField(Subscriber_field3), FormField(Subscriber_field4));
				Space.AddUser(name, username, group);
				userx.AddBlogspace(name, username, group, true);
				Debugger.Spoor("registerSubscriber", "firstname", firstname, "lastname", lastname);
			}
			catch(x_exception e) {
				Debugger.Spoor("registerSubscriber", "Code", e.Code, "Message", e.Message);
				if (e.Code == "error_exists") {
					throw(new x_glitch(this, e.Code, e.Message));
				} else {
					throw(e);
				}
			}
		}
		/// <summary>
		/// Removes a subscriber from the BlogSpace using the fields on the submission form
		/// </summary>
		private void deleteSubscriber() {
		}
		/// <overloads>
		/// Looks for web spam content and removes
		///	- from blogx.1.0.3 (x_broker)
		/// </overloads>
		/// <summary>
		///	specified spam word list
		/// </summary>
		private bool spamCheck(string checkList, string input, bool raiseError) {
			bool retval = false;
			try {
				string test = input.ToLower();
				string delimStr = "|";
			    char [] delimiter = delimStr.ToCharArray();
				string [] split = null;
				split = checkList.Split(delimiter);
				foreach (string s in split) {
					if (test.IndexOf(s) >= 0) {
						retval = true;
						break;
					}
	            }
			} catch (Exception e) {
				throw(new x_exception("error_content_spam", String.Concat(e.Message, " : ", e.StackTrace)));
			}
			
			if (raiseError && retval)
				throw(new x_exception("error_content_spam", error_content_spam));
			return retval;
		}
		/// <summary>
		///	default spam word list
		/// </summary>
		private bool spamCheck(string input, bool raiseError) {
			return spamCheck(spam_list, input, raiseError);
		}
		#endregion
	}
}
